package com.caits.lbs.framework.action;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.dom4j.Document;
import org.dom4j.Element;

import com.caits.lbs.framework.Constants;
import com.caits.lbs.framework.log.CommonLogFactory;
import com.caits.lbs.framework.utils.Dom4jXmlUtil;
import com.caits.lbs.framework.utils.FileUtils;
import com.caits.lbs.framework.utils.JsonUtils;
import com.caits.lbs.framework.utils.StringUtils;
import com.common.ajax.server.IRequest;
import com.opensymphony.xwork2.ActionSupport;

/**
 * <p>
 * BaseAction
 * </p>
 * <p>
 * 用途：基础的action,所有的业务action都继承此action
 * 提供了处理接口IRequest，全局配置类Constants,session对象，通用xml包装
 * </p>
 * 
 * @author 周华彬(zhouhuabin@ctfo.com, zhou_hua_bin@163.com)
 * @version 0.0.1 2011-8-25
 *          <table style="border:1px solid gray;">
 *          <tr>
 *          <th width="100px">版本号</th>
 *          <th width="100px">动作</th>
 *          <th width="100px">修改人</th>
 *          <th width="100px">修改时间</th>
 *          </tr>
 *          <!-- 以 Table 方式书写修改历史 -->
 *          <tr>
 *          <td>0.0.0</td>
 *          <td>创建类</td>
 *          <td>zhb</td>
 *          <td>2011-8-25 下午2:38:12</td>
 *          </tr>
 *          <tr>
 *          <td>0.0.1</td>
 *          <td>创建类</td>
 *          <td>zhb</td>
 *          <td>2011-8-25 下午2:38:12</td>
 *          <td>0.0.2</td>
 *          <td>修改类</td>
 *          <td>xxx</td>
 *          <td>x年x月x日</td>
 *          </tr>
 *          </table>
 */
public abstract class BaseAction extends ActionSupport implements SessionAware,
		ServletRequestAware, ServletResponseAware {
	/** 序列号 */
	private static final long serialVersionUID = 1L;

	/**内容编码参见网址
	 * http://www.utoronto.ca/webdocs/HTMLdocs/Book/Book-3ed/appb/mimetype.html*
	 */
	/** 内容编码utf-8 */
	public final static String ContentTypeUtf8 = "text/plain;charset=UTF-8";
	/** 内容编码gbk */
	public final static String ContentTypeGBK = "text/plain;charset=GBK";
	/** 内类型 (xml格式,utf-8)*/
	public final static String ContentTypeXMLUtf8 = "text/xml;charset=UTF-8";
	/** 内类型 (xml格式,GBK)*/
	public final static String ContentTypeXMLGBK = "text/xml;charset=GBK";
	/** 内容类型(json,utf8数据) */
	public final static String ContentTypeJsonUtf8 = "text/json;charset=UTF-8";
	/** 内容类型(json,gbk数据) */
	public final static String ContentTypeJsonGBK = "text/json;charset=GBK";
	/** 内容类型(二进制流格式)*/
	public final static String ContentTypeBin = "application/octet-stream";
	/** 内容类型Content-Disposition,下载文件名称*/
	public final static String ContentTypeDisposition = "attachment;filename=";
	/** 内容类型(压缩文件格式)*/
	public final static String ContentTypeZip = "application/zip";
	
	/** log4j 日志记录器 */
	protected Logger log = CommonLogFactory.getLog();

	/** 请求 */
	private HttpServletRequest request;
	/** 响应 */
	private HttpServletResponse response;
	/** 存放一个会话对象 */
	private Map<String, Object> session;
	/** 处理对象 */
	private IRequest serviceParser;

	/** 全局常量配置 */
	private Constants constants;

	/**
	 * 构造器
	 */
	public BaseAction() {
		super();
	}

	// **************************************************************************

	public HttpServletRequest getRequest() {
		return request;

	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	/**
	 * @return
	 */
	public Map<String, Object> getSession() {
		return session;
	}

	/* (non-Javadoc)
	 * @see org.apache.struts2.interceptor.SessionAware#setSession(java.util.Map)
	 */
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	/* (non-Javadoc)
	 * @see org.apache.struts2.interceptor.ServletRequestAware#setServletRequest(javax.servlet.http.HttpServletRequest)
	 */
	public void setServletRequest(HttpServletRequest arg0) {
		this.request = arg0;
	}

	/* (non-Javadoc)
	 * @see org.apache.struts2.interceptor.ServletResponseAware#setServletResponse(javax.servlet.http.HttpServletResponse)
	 */
	public void setServletResponse(HttpServletResponse arg0) {
		this.response = arg0;
	}

	/**
	 * 获取变量<code>constants</code>的值
	 * 
	 * @return 返回的数据类型是<code>Constants</code>
	 */
	public Constants getConstants() {
		return constants;
	}

	/**
	 * 设置变量<code> constants</code> 的值
	 * 
	 * @param constants
	 *            <code>constants</code> 参数类型是<code>Constants</code>
	 */
	public void setConstants(Constants constants) {
		this.constants = constants;
	}

	/**
	 * 检查验证码
	 * 
	 * @param code
	 * @return
	 */
	public boolean checkCode(String code) {
		if (code != null) {
			return code.trim().toUpperCase()
					.equals(session.get("RandomCheckCode"));
		}

		return false;
	}

	/**
	 * 获取变量<code>serviceParser</code>的值
	 * 
	 * @return 返回的数据类型是<code>IRequest</code>
	 */
	public IRequest getServiceParser() {
		return serviceParser;
	}

	/**
	 * 设置变量<code> serviceParser</code> 的值
	 * 
	 * @param serviceParser
	 *            <code>serviceParser</code> 参数类型是<code>IRequest</code>
	 */
	public void setServiceParser(IRequest serviceParser) {
		this.serviceParser = serviceParser;
	}


	/**
	 * 清除页面 缓存
	 * @param response
	 */
	public void clearCache(HttpServletResponse response){
		//清除页面
		response.setHeader("Pragma","No-cache");
		response.setHeader("Cache-Control","no-cache");
		response.setHeader("Cache-Control", "no-store");
		response.setDateHeader("Expires", 0);
	}
	/**
	 * 代理第三方服务接收客户端请求，返回相应结果给客户端
	 * 需要参数url
	 */
	public void proxy3rdServer() {
		HttpServletRequest request =  getRequest();
		HttpServletResponse response = getResponse();
		response.setContentType(ContentTypeUtf8);
		OutputStream output = null;
		String result = null;
		try {
			output = response.getOutputStream();
			String targetUrl = request.getParameter("url");
			if(StringUtils.isNullOrBlank(targetUrl)){
				result = "代理服务缺少目标地址url参数";
				log.error(result);
				output.write(result.getBytes());
				return;//仍会执行finally代码
			}
			if(!FileUtils.filePath2Stream(targetUrl,output,FileUtils.CONST_BUFFERSIZE_100K)){
				result = "请求远程url时不成功,url=" +targetUrl;
				log.error(result);
			}
		} catch (RuntimeException e) {
			result = "服务处理运行时错误,msg=" + e.getLocalizedMessage();
			log.error(result, e);
		}catch(Exception e){
			result= "服务处理错误,msg=" + e.getLocalizedMessage();
			log.error(result, e);
		}finally{
			try {
				if(result!=null){
					log.info("代理服务返回的结果：" + prettyStringLengh(result));
					output.write(result.getBytes(FileUtils.CONST_DEFAULT_CHARSET));
				}
				output.flush();
				output.close();
			} catch (IOException e) {
				log.error("服务输出结果错误,msg=" + e.getLocalizedMessage(), e);
			}// 返回相应结果
			
		}
	}
	/**
	 * 将xml转换为json格式 
	 * @param doc
	 * @param type ==1时 返回纯数据数组, ==0时整个结构
	 * @return
	 */
	public String buildJsonByDocument(Document doc,int type) {
		try{
			Element resResponse = doc.getRootElement();
			String server=resResponse.attributeValue(IRequest.XML_SERVER);
			Element resData = (Element) resResponse.elements(IRequest.XML_DATA).get(0);
			resData.addAttribute("result", "1");
			List<Element> list = resData.elements();
			List<Map<String, Object>> resultList= new ArrayList<Map<String,Object>>();
			for(Element base:list)
			{
				Map<String, Object> map = Dom4jXmlUtil.elementToMap(base);
				resultList.add(map);
			}
			Map<String,Object> data =Dom4jXmlUtil.elementToMap(resData);
			data.put("list",resultList);
			if(type==1){
				return JsonUtils.getJsonStringFromObject(resultList);
			}
			Map<String,Object> bean= new HashMap<String,Object>();
			bean.put(IRequest.XML_SERVER,server);
			bean.put(IRequest.XML_DATA,data);
			return JsonUtils.getJsonStringFromMap(bean);
		}catch(Exception e){
			log.error("响应结果转换错误,msg="+e.getLocalizedMessage(), e);
			return null;
		}
	}
	/**
	 * 取得系统打印的许可长度
	 * 
	 * @param asXML
	 * @return
	 */
	protected String prettyStringLengh(String asXML) {
		return asXML == null ? null : asXML.substring(0,
				Math.min(constants.getMax_log_output(), asXML.length()));
	
	}

	/**
	 * 复制参数map，并把数组转换成字符串
	 * 并且把key转成小写
	 * @param paramMap
	 * @return
	 */
	protected Map<String, String> buildParamMap2String(Map<String, Object> paramMap) {
		Map<String, String> cloneMap = new HashMap<String, String>();
		for (String key : paramMap.keySet()) {
			Object val = paramMap.get(key);
			String value = "";
			if (val instanceof String) {
				value = (String) val;
			} else {
				String[] arr = (String[]) val;
				value = StringUtils.joinArrays(arr, ",");
			}

			cloneMap.put(key, value);
		}
		return cloneMap;
	}
	/**
	 * 通用方法实现，建议使用,可参考proxy3rdServer
	 */
	public abstract void commonActionParser();
}
